package com.qwc.blog.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qwc.blog.common.enums.ConfigTypeEnum;
import com.qwc.blog.common.exception.BadRequestException;
import com.qwc.blog.entity.Config;
import com.qwc.blog.entity.vo.config.AddConfigDto;
import com.qwc.blog.entity.vo.config.ConfigListReqDto;
import com.qwc.blog.mapper.ConfigMapper;
import com.qwc.blog.service.IConfigService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.qwc.blog.common.constant.CommonConstant.YES;
import static com.qwc.blog.common.constant.ConfigConstant.FRONT_CONFIG;
import static com.qwc.blog.common.constant.ResponseConstant.USED_NAME;

/**
 * <p>
 * 配置表 服务实现类
 * </p>
 *
 * @author qwc
 * @since 2021-11-08
 */
@Service
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, Config> implements IConfigService {

    @Override
    public Page<Config> getConfigList(ConfigListReqDto dto) {
        return baseMapper.selectPage(PageDTO.of(dto.getPageNum(), dto.getPageSize()), Wrappers.<Config>lambdaQuery()
                .like(StringUtils.isNotBlank(dto.getName()), Config::getName, dto.getName())
                .like(StringUtils.isNotBlank(dto.getConfigKey()), Config::getConfigKey, dto.getConfigKey())
                .eq(StringUtils.isNotBlank(dto.getStatus()), Config::getStatus, dto.getStatus()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addConfig(AddConfigDto dto) {
        Config config = dto.createConfig();
        checkParam(config);
        baseMapper.insert(config);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateConfig(AddConfigDto dto) {
        Config config = dto.createConfig();
        config.setUpdateTime(new Date());
        checkParam(config);
        baseMapper.updateById(config);
    }

    @Override
    public Map<String, String> getFrontConfig() {
        List<Config> configs = baseMapper.selectList(Wrappers.<Config>lambdaQuery()
                .eq(Config::getStatus, YES)
                .eq(Config::getType, ConfigTypeEnum.FRONT.getKey()));
        return configs.stream().collect(Collectors.toMap(Config::getConfigKey, Config::getConfigValue));
    }

    private void checkParam(Config config) {
        List<Config> sameNameConfigs = baseMapper.selectList(Wrappers.<Config>lambdaQuery().eq(Config::getName, config.getName()));
        if (CollUtil.isNotEmpty(sameNameConfigs) && sameNameConfigs.stream().noneMatch(sameName -> sameName.getId().equals(config.getId()))) {
            throw new BadRequestException(USED_NAME);
        }
        List<Config> sameKeyConfigs = baseMapper.selectList(Wrappers.<Config>lambdaQuery().eq(Config::getConfigKey, config.getConfigKey()));
        if (CollUtil.isNotEmpty(sameKeyConfigs) && sameKeyConfigs.stream().noneMatch(sameName -> sameName.getId().equals(config.getId()))) {
            throw new BadRequestException(USED_NAME);
        }
    }
}
